package com.heima.wemedia.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustomizeException;
import com.heima.common.exception.CustomizeExceptionBuilder;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmMaterialDTO;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.threadlocal.WmThreadLocalUtils;
import com.heima.oss.service.FileStorageService;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.IWmMaterialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.ws.Response;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class WmMaterialService extends ServiceImpl<WmMaterialMapper, WmMaterial> implements IWmMaterialService {

    @Value("#{'${allow.list}'.split(',')}")
    private List<String> uploadAllowed;
    @Value("${file.oss.prefix}")
    private String prefix;
    @Value("${file.oss.web-site}")
    private String webSite;

    @Autowired
    private FileStorageService fileStorageService;

    /**
     * 素材管理 - 图片上传
     * @param multipartFile
     * @return
     */
    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) {
        //1.校验参数
            //1.1判断上传文件是否为空
        if(multipartFile == null || multipartFile.getSize() == 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "上传文件不能为空");
        }
            //1.2检查文件的后缀名是否符合 【jpg、png、jepg、gif】
        String originalFilename = multipartFile.getOriginalFilename();
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
        if(!uploadAllowed.contains(suffixName)){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_ALLOW, "当前文件类型不允许被上传");
        }
            //1.3当前操作需要自媒体用户已登录
        Integer userId = WmThreadLocalUtils.getUser();
        if(userId == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "当前操作需要登录，请先登录");
        }
        //2.上传图片
        String storePath = "";
        try {
            String filename = UUID.randomUUID().toString().replaceAll("-", "") + suffixName;
            storePath = fileStorageService.store(prefix, filename, multipartFile.getInputStream());
            log.info("阿里云OSS 文件 fileId: {}", storePath);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("阿里云文件上传失败 uploadPicture error: {}", e);
            CustomizeExceptionBuilder.builder(AppHttpCodeEnum.SERVER_ERROR,"服务器繁忙请稍后重试");
        }
        //3.将素材信息写入到数据表中
        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(userId);
        wmMaterial.setUrl(storePath);
        wmMaterial.setType((short) 0);  //素材的类型 【0(图片)、1(视频)】
        wmMaterial.setIsCollection((short) 0);  //素材是否被收藏 【0(未被收藏)、1(已被收藏)】
        wmMaterial.setCreatedTime(new Date());
        this.save(wmMaterial);
        //4.返回响应，前端需要拿到图片访问路径
        wmMaterial.setUrl(webSite + wmMaterial.getUrl());
        return ResponseResult.okResult(wmMaterial);
    }

    @Override
    public ResponseResult findList(WmMaterialDTO wmMaterialDTO) {
        //1.校验参数
        wmMaterialDTO.checkParam();
        //2.查询素材
            //2.1组装分页条件
        IPage<WmMaterial> pageQuery = new Page<>(wmMaterialDTO.getPage(), wmMaterialDTO.getSize());
            //2.2组装收藏条件
        LambdaQueryWrapper<WmMaterial> queryWrapper = Wrappers.<WmMaterial>lambdaQuery();
        if(wmMaterialDTO.getIsCollection() != null && wmMaterialDTO.getIsCollection() == 1) {
            queryWrapper.eq(WmMaterial::getIsCollection, wmMaterialDTO.getIsCollection());
        }
            //2.3过滤当前登录用户的素材
        Integer userId = WmThreadLocalUtils.getUser();
        if(userId == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "需要登录后才能操作，请先登录");
        }
        queryWrapper.eq(WmMaterial::getUserId, userId);
            //2.4按照素材创建时间的倒序排序
        queryWrapper.orderByDesc(WmMaterial::getCreatedTime);
        IPage<WmMaterial> pageResult = this.page(pageQuery, queryWrapper);
        //3.返回结果
            //3.1返回的所有素材的路径为完整路径
        List<WmMaterial> wmMaterialList = pageResult.getRecords();
        for (WmMaterial wmMaterial : wmMaterialList) {
            wmMaterial.setUrl(webSite + wmMaterial.getUrl());
        }
        PageResponseResult responseResult = new PageResponseResult(wmMaterialDTO.getPage(), wmMaterialDTO.getSize(), pageResult.getTotal(), wmMaterialList);
        return responseResult;
    }

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Override
    public ResponseResult deletePicture(Integer id) {
        //1.校验参数
        if(id == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "素材 id 不能为空");
        }
            //1.1判断当前素材是否是脏数据
        WmMaterial wmMaterial = this.getById(id);
        if(wmMaterial == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "素材不存在");
        }
        Integer userId = WmThreadLocalUtils.getUser();
        if(userId == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "需要登录后才能操作，请先登录");
        }
            //1.2被文章引用的素材不能删除
        Integer count = wmNewsMaterialMapper.selectCount(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getMaterialId, id));
        if(count > 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_ALLOW, "该素材被引用中，不可删除");
        }
        //2.删除素材
        this.removeById(id);
        //3.删除 OSS 中的素材
        fileStorageService.delete(wmMaterial.getUrl());
        //4.响应结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult updatePicture(Integer id, Short isCollection) {
        //1.校验参数
        if(id == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
            //1.1判断当前素材是否是脏数据
        WmMaterial wmMaterial = this.getById(id);
        if(wmMaterial == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "素材数据不存在");
        }
            //1.2判断用户是否登录
        Integer userId = WmThreadLocalUtils.getUser();
        if(userId == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "需要登录后才能操作，请先登录");
        }
        //2.修改素材状态
        LambdaUpdateWrapper<WmMaterial> updateWrapper = Wrappers.<WmMaterial>lambdaUpdate();
        updateWrapper.set(WmMaterial::getIsCollection, isCollection).eq(WmMaterial::getUserId, userId).eq(WmMaterial::getId, id);
        this.update(updateWrapper);
        //3.响应结果
        return ResponseResult.okResult();
    }
}
